// 互斥锁

#include <iostream>
#include <pthread.h>
#include <string>
#include <vector>
#include <unistd.h>
//////// 演示什么是数据不一致 !

int gticksts = 1000; // 总票数

// 1. 定义一个全局的锁
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // INITIALIZER - initiallizer 初始化

// 2. 定义了一个局部锁
pthread_mutex_t mutex;

// 这个是抢票 , 票数为 1000 , 多个线程来执行
void *Tickets(void *args)
{
    std::string name = static_cast<const char *>(args);

    while (1)
    {

        // 这里是临界区的开始 , 因为里面访问了共享资源
        // 这里加锁
        pthread_mutex_lock(&mutex);
        if (gticksts > 0)
        {
            usleep(1000); // 1000 ms
            std::cout << name << " sells ticket : " << gticksts << std::endl;
            gticksts--;
            // 这里解锁
            pthread_mutex_unlock(&mutex);
        } // 到这里临界区的结束 ..
        else
        {
            // 这里必须解锁 !!!!!!!!!!!!!  防止出现死锁 , 当票数 = 0 时会走这里
            pthread_mutex_unlock(&mutex);
            break;
        }
    }

    return nullptr;
}

int main()
{
    std::vector<pthread_t> threads;

    // 局部锁初始化
    pthread_mutex_init(&mutex, nullptr);

    // 创建5个线程
    for (int i = 1; i <= 5; ++i)
    {
        pthread_t tid;
        char *name = new char[64]; // 开辟一个空间
        snprintf(name, 64, "thread-%d", i);
        int n = pthread_create(&tid, nullptr, Tickets, name);
        if (n == 0)
        {
            std::cout << "Create " << name << " Success ! " << std::endl;
            threads.emplace_back(tid);
        }
    }

    // 等待 5 个线程
    for (auto &tid : threads)
    {
        int n = pthread_join(tid, nullptr);
        if (n == 0)
        {
            std::cout << " Join Success ! " << std::endl;
        }
    }

    // 2. 定义局部锁时 :
    // 这里销毁锁
    pthread_mutex_destroy(&mutex);

    return 0;
}